<script>
import ZxScrollbar from '../../../components/scrollbar';
import CascaderNode from './cascader-node';
import Locale from '@src/mixins/locale';
import { generateId } from '@src/utils/util';

export default {
    name: 'ZxCascaderMenu',

    components: {
        ZxScrollbar,
        CascaderNode,
    },

    mixins: [Locale],

    inject: ['panel'],

    props: {
        nodes: {
            type: Array,
            required: true,
        },
        index: Number,
    },

    data() {
        return {
            activeNode: null,
            hoverTimer: null,
            id: generateId(),
        };
    },

    computed: {
        isEmpty() {
            return !this.nodes.length;
        },
        menuId() {
            return `cascader-menu-${this.id}-${this.index}`;
        },
    },

    methods: {
        handleExpand(e) {
            this.activeNode = e.target;
        },
        handleMouseMove(e) {
            const { activeNode, hoverTimer } = this;
            const { hoverZone } = this.$refs;

            if (!activeNode || !hoverZone) return;

            if (activeNode.contains(e.target)) {
                clearTimeout(hoverTimer);

                const { left } = this.$el.getBoundingClientRect();
                const startX = e.clientX - left;
                const { offsetWidth, offsetHeight } = this.$el;
                const top = activeNode.offsetTop;
                const bottom = top + activeNode.offsetHeight;

                hoverZone.innerHTML = `
          <path style="pointer-events: auto;" fill="transparent" d="M${startX} ${top} L${offsetWidth} 0 V${top} Z" />
          <path style="pointer-events: auto;" fill="transparent" d="M${startX} ${bottom} L${offsetWidth} ${offsetHeight} V${bottom} Z" />
        `;
            } else if (!hoverTimer) {
                this.hoverTimer = setTimeout(this.clearHoverZone, this.panel.config.hoverThreshold);
            }
        },
        clearHoverZone() {
            const { hoverZone } = this.$refs;
            if (!hoverZone) return;
            hoverZone.innerHTML = '';
        },

        renderEmptyText(h) {
            return (
        <div class="zx-cascader-menu__empty-text">{ this.t('el.cascader.noData') }</div>
            );
        },
        renderNodeList(h) {
            const { menuId } = this;
            const { isHoverMenu } = this.panel;
            const events = { on: {} };

            if (isHoverMenu) {
                events.on.expand = this.handleExpand;
            }

            const nodes = this.nodes.map((node, index) => {
                const { hasChildren } = node;
                return (
                <cascader-node
                  key={ node.uid }
                  node={ node }
                  node-id={ `${menuId}-${index}` }
                  aria-haspopup={ hasChildren }
                  aria-owns = { hasChildren ? menuId : null }
                  { ...events }></cascader-node>
                );
            });

            return [
                ...nodes,
                isHoverMenu ? <svg ref='hoverZone' class='zx-cascader-menu__hover-zone'></svg> : null,
            ];
        },
    },

    render(h) {
        const { isEmpty, menuId } = this;
        const events = { nativeOn: {} };

        // optimize hover to expand experience (#8010)
        if (this.panel.isHoverMenu) {
            events.nativeOn.mousemove = this.handleMouseMove;
            // events.nativeOn.mouseleave = this.clearHoverZone;
        }

        return (
            <zx-scrollbar
                tag="ul"
                role="menu"
                id={ menuId }
                class="zx-cascader-menu"
                wrap-class="zx-cascader-menu__wrap"
                view-class={{
                    'zx-cascader-menu__list': true,
                    'is-empty': isEmpty,
                }}
                { ...events }>
                { isEmpty ? this.renderEmptyText(h) : this.renderNodeList(h) }
            </zx-scrollbar>
        );
    },
};
</script>
